// 这个属性用于隐藏未使用代码的警告
#![allow(dead_code)]

mod c_style;
mod enum_list;

#[derive(Debug)]
enum RoadMap {
    Rust入门指南,
    Rust权威指南,
    Rust项目实战,
}

// 创建一个`enum` 来分类网页事件。
// 注意名称和类型信息如何共同指定变体：
// `PageLoad != PageUnload` 且 `KeyPress(char)!= Paste(String)`
// 每个变体都是不同且独立的。
enum WebEvent {
    PageLoad,
    PageUnload,
    KeyPress(char),
    Paste(String),
    Click { x: i64, y: i64 },
}
// 一个接受 `WebEvent` 枚举作为参数且不返回任何值的函数。
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("页面已加载"),
        WebEvent::PageUnload => println!("页面已卸载"),
        // 从 enum 变体内部结构 c
        WebEvent::KeyPress(c) => println!("按下了'{}'键。", c),
        WebEvent::Paste(s) => println!("粘贴了\"{}\"。", s),
        // 将 click 解构为 x 和 y
        WebEvent::Click { x, y } => {
            println!("点击坐标: x={},y={}", x, y)
        }
    }
}

// 类型别名
enum VeryVerboseEnumOfThingsToDoWithNumbers {
    Add,
    Subtract,
}

// 使用类型别名可以通过别名引用每个枚举变体。当枚举名称过长或过于泛化，而你想重命名它时，这会很有用。
// 创建类型别名
type Operations = VeryVerboseEnumOfThingsToDoWithNumbers;

// 你最常见到这种用法的地方是在使用 Self 别名的 impl 块中。
impl VeryVerboseEnumOfThingsToDoWithNumbers {
    fn run(&self, x: i32, y: i32) -> i32 {
        match self {
            Self::Add => x + y,
            Self::Subtract => x - y,
        }
    }
}

fn main() {
    let level = RoadMap::Rust入门指南;
    println!("level---{:?}", level);

    let p = 666;
    let result = get_discount(p);
    // println!("{:?}",result);
    println!("{}", result.is_none());
    println!("{}", result.is_some());
    if result.is_some() {
        // 使用unwrap方法获取Some枚举内的值
        println!("{}", result.unwrap())
    }

    print_road_map(RoadMap::Rust权威指南);
    print_road_map(RoadMap::Rust项目实战);
    print_road_map(RoadMap::Rust入门指南);

    let pressed = WebEvent::KeyPress('x');
    // `to_owned()` 从字符串切片创建一个拥有所有权的 `String`。
    let pasted = WebEvent::Paste("我的文本".to_owned());
    let click = WebEvent::Click { x: 20, y: 80 };
    let load = WebEvent::PageLoad;
    let unload = WebEvent::PageUnload;

    inspect(pressed);
    inspect(pasted);
    inspect(click);
    inspect(load);
    inspect(unload);

    // 我们可以通过别名引用每个变体，而不是使用又长又不便的名称。
    let x = Operations::Add;
    let sum = x.run(4, 6);
    println!("{}",sum)
}

fn get_discount(price: i32) -> Option<String> {
    if price > 100 {
        Some(String::from("大于100，符合要求"))
    } else {
        None
    }
}

fn print_road_map(r: RoadMap) {
    match r {
        RoadMap::Rust入门指南 => {
            println!("RoadMap->Rust入门指南")
        }
        RoadMap::Rust权威指南 => {
            println!("RoadMap->Rust权威指南")
        }
        RoadMap::Rust项目实战 => {
            println!("RoadMap->Rust项目实战")
        }
    }
}